home *** CD-ROM | disk | FTP | other *** search
/ BBS Toolkit / BBS Toolkit.iso / remote / u_orig.zip / U-ORIG.C next >
C/C++ Source or Header  |  1992-07-09  |  25KB  |  716 lines

  1.  
  2. /* **********************************************************************
  3.    * U-Orig.C  User specific origin lines.                              *
  4.    *                                                                    *
  5.    * For RemoteAccess.                                                  *
  6.    *                                                                    *
  7.    * Written by Fredric L. Rice, 1992, The Skeptic Tank, 1:102/890.0.   *
  8.    *                                                                    *
  9.    * This program will scan the DOREINFO1.DEF file which looks a bit    *
  10.    * like this:                                                         *
  11.    *                                                                    *
  12.    *   THE SKEPTIC TANK                                                 *
  13.    *   FREDRIC                                                          *
  14.    *   RICE                                                             *
  15.    *   COM0                                                             *
  16.    *   0 BAUD,N,8,1                                                     *
  17.    *   0                                                                *
  18.    *   FREDRIC                                                          *
  19.    *   RICE                                                             *
  20.    *   GLENDORA, CA                                                     *
  21.    *   1                                                                *
  22.    *   6000                                                             *
  23.    *   287                                                              *
  24.    *                                                                    *
  25.    * The name of the user is extracted and it is compared against an    *
  26.    * entry in the U-ORIG.DAT file to see if this user has created a new *
  27.    * origin line for himself or herself. If the name is found, the text *
  28.    * for the origin line is selected, else the default origin line      *
  29.    * which is found in the U-ORIG.CFG file is used.                     *
  30.    *                                                                    *
  31.    * The origin information is inserted into the MESSAGES.RA file which *
  32.    * contains the name of the conference (The title) along with the     *
  33.    * origin line to use.  This is acceptable for people who don't want  *
  34.    * to change the default origin line as the SysOp will define one for *
  35.    * them.                                                              *
  36.    *                                                                    *
  37.    ********************************************************************** */
  38.  
  39. #include <bios.h>
  40. #include <ctype.h>
  41. #include <conio.h>
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #include <time.h>
  46.  
  47. /* **********************************************************************
  48.    * How about any macros.                                              *
  49.    *                                                                    *
  50.    ********************************************************************** */
  51.  
  52. #define skipspace(s)    while(isspace(*s))  ++(s)
  53. #define TRUE            1
  54. #define FALSE           0
  55. #define BOOL            unsigned char
  56.  
  57. /* **********************************************************************
  58.    * Define macros that the System Operator may wish to change.         *
  59.    *                                                                    *
  60.    ********************************************************************** */
  61.  
  62. #define Input_Time_Out  30    /* 30 second keyboard time-out */
  63.  
  64. /* **********************************************************************
  65.    * Define some global data.                                           *
  66.    *                                                                    *
  67.    ********************************************************************** */
  68.  
  69.     static char default_origin[201];
  70.     static char origin_to_use[201];
  71.     static char full_path[201];
  72.     static char user_name[201];
  73.     static time_t t_start, t_end;
  74.     static int com_assignment;
  75.     static int user_count = 0;
  76.     static BOOL local_mode;
  77.     static long security_value = 0L;
  78.     static long allowed_security = 0L;
  79.  
  80. /* **********************************************************************
  81.    * Here is the data structure for the MESSAGES.RA file that we know   *
  82.    * about. Some of the informations format is not known yet we will    *
  83.    * simply bypass it all.                                              *
  84.    *                                                                    *
  85.    ********************************************************************** */
  86.  
  87.     static struct Messages_RA {
  88.         char title_length;              /* 1 byte length of next field. */
  89.         char title[40];                 /* Title of the folder */
  90.         char unknown[25];               /* Unkown so we'll simply skip them */
  91.         char origin_length;             /* 1 byte length of next field */
  92.         char origin[61];                /* Origin line of the folder */
  93.     } MRA;                              /* Make one called 'MRA.' */
  94.  
  95. /* **********************************************************************
  96.    * Return TRUE if there is a byte waiting, else return FALSE.         *
  97.    *                                                                    *
  98.    ********************************************************************** */
  99.  
  100. static BOOL have_byte(void)
  101. {
  102.     int result;
  103.  
  104.     if (kbhit() != 0) return(TRUE);
  105.  
  106.     if (! local_mode) {
  107.         result = bioscom(3, 0, com_assignment);
  108.         return((result & 0x0100) != 0);
  109.     }
  110.  
  111.     return(FALSE);
  112. }
  113.  
  114. /* **********************************************************************
  115.    * Get the byte.                                                      *
  116.    *                                                                    *
  117.    ********************************************************************** */
  118.  
  119. static unsigned char get_byte(void)
  120. {
  121.     int result;
  122.  
  123.     if (kbhit() != 0)
  124.         return(getch());
  125.  
  126.     if (! local_mode) {
  127.         result = bioscom(2, 0, com_assignment);
  128.         return(result & 0xFF);
  129.     }
  130.  
  131.     return(0);
  132. }
  133.  
  134. /* **********************************************************************
  135.    * Simply send a byte.                                                *
  136.    *                                                                    *
  137.    ********************************************************************** */
  138.  
  139. static void send_byte(unsigned char byte)
  140. {
  141.     if (!local_mode) {
  142.         if (byte != 0x0d) {
  143.             if (byte == 0x0a) {
  144.                 (void)bioscom(1, 0x0d, com_assignment);
  145.                 if (have_byte()) {
  146.                     (void)get_byte();
  147.                 }
  148.             }
  149.  
  150.             (void)bioscom(1, byte, com_assignment);
  151.         }
  152.     }
  153.  
  154.     (void)putchar(byte);                                     
  155.  
  156.     if (! local_mode) {
  157.         if (have_byte()) {
  158.             (void)get_byte();
  159.         }
  160.     }
  161. }
  162.  
  163. /* **********************************************************************
  164.    * Send the string.                                                   *
  165.    *                                                                    *
  166.    ********************************************************************** */
  167.    
  168. static void print_buffer(char *message)
  169. {
  170.     while (*message)
  171.         send_byte(*message++);
  172. }
  173.  
  174. /* **********************************************************************
  175.    * Get some input.                                                    *
  176.    *                                                                    *
  177.    * This function is a very simple input function which supplies only  *
  178.    * a few features.                                                    *
  179.    *                                                                    *
  180.    * Backspace is checked for and will erase the input data stream if   *
  181.    * any remains.                                                       *
  182.    *                                                                    *
  183.    * It performs bounds checking to see if the input length would       *
  184.    * exceed the length of the buffer.                                   *
  185.    *                                                                    *
  186.    * It employs the inactivity time-out timers.                         *
  187.    *                                                                    *
  188.    ********************************************************************** */
  189.  
  190. static void input(char *to_this, int how_many)
  191. {
  192.     int b_count;
  193.     char byte, report[10];
  194.     time_t t_start, t_end;
  195.  
  196.     b_count = 0;
  197.  
  198.     (void)time(&t_start);
  199.     (void)time(&t_end);
  200.  
  201. /*
  202.     An endless loop will help. A time-out is employed to make sure
  203.     that we exit the program if no keys are typed after a long time
  204.     only if the program is being run on a COM port.
  205. */
  206.  
  207.     while (TRUE) {
  208.  
  209.         (void)time(&t_end);
  210.  
  211.         if (difftime(t_end, t_start) > Input_Time_Out) {
  212.             print_buffer("\n!!! Keyboard Timed out !!!\n");
  213.             (void)fcloseall();
  214.             exit(11);
  215.         }
  216.  
  217.         if (have_byte()) {
  218.             byte = get_byte();
  219.  
  220.             if (byte > 0) {
  221.                 if (byte == 0x08) {         /* Backspace? */
  222.                     if (b_count > 0) {
  223.                         to_this[b_count--] = (char)NULL;
  224.                         (void)sprintf(report, "%c %c", 0x08, 0x08);
  225.                         print_buffer(report);
  226.                     }
  227.                 }
  228.                 else if (byte == 0x0d) {    /* Carriage return? */
  229.                     putchar(0x0d);
  230.                     putchar(0x0a);
  231.                     (void)send_byte(0x0d);
  232.                     (void)send_byte(0x0a);
  233.                     return;
  234.                 }
  235.                 else {
  236.                     if ((b_count + 1) == how_many) {
  237.                         send_byte(0x07);
  238.                     }
  239.                     else {
  240.                         to_this[b_count++] = byte;
  241.                         to_this[b_count] = (char)NULL;
  242.                         (void)send_byte(byte); /* Echo to port */
  243.                     }
  244.                 }
  245.             }
  246.         }
  247.     }
  248. }
  249.  
  250. /* **********************************************************************
  251.    * Get the configuration out of the U-ORIG.CFG file.                  *
  252.    *                                                                    *
  253.    ********************************************************************** */
  254.    
  255. static void extract_configuration(void)
  256. {
  257.     FILE *config;
  258.     char record[201], *point;
  259.  
  260.     if ((config = fopen("U-ORIG.CFG", "rt")) == (FILE *)NULL) {
  261.         (void)printf("Unable to locate config file: U-ORIG.CFG!\n");
  262.         fcloseall();
  263.         exit(10);
  264.     }
  265.  
  266.     (void)strcpy(default_origin, ".");
  267.     (void)strcpy(full_path, ".");
  268.  
  269.     while (! feof(config)) {
  270.         (void)fgets(record, 200, config);
  271.  
  272.         if (! feof(config)) {
  273.             point = record;
  274.             skipspace(point);
  275.  
  276.             if (! strnicmp(point, "default", 7)) {
  277.                 point += 7;
  278.                 skipspace(point);
  279.                 point[strlen(point) - 1] = (char)NULL;
  280.                 (void)strcpy(default_origin, point);
  281.             }
  282.             else if (! strnicmp(point, "path", 4)) {
  283.                 point += 4;
  284.                 skipspace(point);
  285.                 point[strlen(point) - 1] = (char)NULL;
  286.                 (void)strcpy(full_path, point);
  287.  
  288.         if (full_path[strlen(full_path) - 1] != '\\') {
  289.                     (void)strcat(full_path, "\\");
  290.                 }
  291.             }
  292.             else if (! strnicmp(point, "security", 8)) {
  293.                 point += 8;
  294.                 skipspace(point);
  295.                 allowed_security = atol(point);
  296.             }
  297.         }
  298.     }
  299.  
  300.     (void)fclose(config);
  301.  
  302.     if (default_origin[0] == '.' && default_origin[1] == (char)NULL) {
  303.         (void)printf("Config file is missing 'default' statement!\n");
  304.         fcloseall();
  305.         exit(10);
  306.     }
  307.  
  308.     if (full_path[0] == '.' && full_path[1] == (char)NULL) {
  309.         (void)printf("Config file is missing 'path' statement!\n");
  310.         fcloseall();
  311.         exit(10);
  312.     }
  313.  
  314.     if (allowed_security == 0L) {
  315.         (void)printf("Config file is missing 'security' statement!\n");
  316.         fcloseall();
  317.         exit(10);
  318.     }
  319. }
  320.  
  321. /* **********************************************************************
  322.    * Get the users name out of the door file.                           *
  323.    *                                                                    *
  324.    ********************************************************************** */
  325.  
  326. static void extract_door_file(void)
  327. {
  328.     FILE *door;
  329.     char record[201], *point;
  330.     char file_name[201];
  331.     unsigned char loop;
  332.  
  333.     (void)sprintf(file_name, "%s%s", full_path, "DORINFO1.DEF");
  334.  
  335.     if ((door = fopen(file_name, "rt")) == (FILE *)NULL) {
  336.         (void)printf("Unable to locate door file: %s!\n", file_name);
  337.         fcloseall();
  338.         exit(10);
  339.     }
  340.  
  341.     for (loop = 0; loop < 3; loop++)
  342.         (void)fgets(record, 200, door);
  343.  
  344. /*
  345.  * Get the COM port assignment
  346.  */
  347.  
  348.     (void)fgets(record, 200, door);             /* COMn assignment */
  349.  
  350.     if (! feof(door)) {
  351.         point = record;
  352.         skipspace(point);
  353.         point += 3;
  354.         com_assignment = atoi(point);
  355.  
  356.         if (*point != '0') com_assignment--;
  357.     }
  358.     else {
  359.         (void)printf("DORINFO1.DEF file is missing COM port assignment!\n");
  360.         fcloseall();
  361.         exit(10);
  362.     }
  363.  
  364.     if (com_assignment > 8 || com_assignment < 0) {
  365.         (void)printf("DORINFO1.DEF file has strange COM port assignment!\n");
  366.         fcloseall();
  367.         exit(10);
  368.     }
  369.  
  370.     (void)fgets(record, 200, door);             /* Baud rate */
  371.     (void)fgets(record, 200, door);             /* Unknown */
  372.  
  373. /*
  374.  * Read the first name
  375.  */
  376.  
  377.     (void)fgets(record, 200, door);             /* Get first name */
  378.  
  379.     if (! feof(door)) {
  380.         point = record;
  381.         skipspace(point);
  382.         point[strlen(point) - 1] = (char)NULL;
  383.         (void)strcpy(user_name, point);
  384.         (void)strcat(user_name, " ");
  385.     }
  386.     else {
  387.         (void)printf("DORINFO1.DEF file is missing first name!\n");
  388.         fcloseall();
  389.         exit(10);
  390.     }
  391.  
  392.     (void)fgets(record, 200, door);             /* Get second name */
  393.  
  394.     if (! feof(door)) {
  395.         point = record;
  396.         skipspace(point);
  397.         point[strlen(point) - 1] = (char)NULL;
  398.         (void)strcat(user_name, point);
  399.     }
  400.     else {
  401.         (void)printf("DORINFO1.DEF file is missing first name!\n");
  402.         fcloseall();
  403.         exit(10);
  404.     }
  405.  
  406.     (void)fgets(record, 200, door);             /* City and state */
  407.     (void)fgets(record, 200, door);             /* Another line to ignore */
  408.  
  409.     (void)fgets(record, 200, door);             /* Security */
  410.     security_value = atol(record);
  411.  
  412.     (void)fclose(door);
  413.     (void)printf("User: '%s'\n", user_name);
  414. }
  415.  
  416. /* **********************************************************************
  417.    * Scan the U-ORIG file name for a match if there is one. If there    *
  418.    * is, copy the users origin line to the 'origin_to_use' array and    *
  419.    * then return. If there is not, copy the default_origin to the       *
  420.    * 'origin_to_use' array and then return.                             *
  421.    *                                                                    *
  422.    ********************************************************************** */
  423.  
  424. static BOOL match_user_name(void)
  425. {
  426.     FILE *data_file;
  427.     char file_name[201];
  428.     char record[201], *point;
  429.     int search_length;
  430.  
  431.     (void)sprintf(file_name, "%s%s", full_path, "U-ORIG.DAT");
  432.  
  433.     if ((data_file = fopen(file_name, "rt")) == (FILE *)NULL) {
  434.         (void)strcpy(origin_to_use, default_origin);
  435.         (void)printf("Origin: DEFAULT\n");
  436.         return(FALSE);
  437.     }
  438.  
  439.     search_length = strlen(user_name);
  440.  
  441.     while (! feof(data_file)) {
  442.         (void)fgets(record, 200, data_file);
  443.  
  444.         if (! feof(data_file)) {
  445.             point = record;
  446.             skipspace(point);
  447.  
  448.         if (! strnicmp(point, user_name, search_length)) {
  449.         point += search_length;
  450.                 skipspace(point);
  451.                 point[strlen(point) - 1] = (char)NULL;
  452.                 (void)strcpy(origin_to_use, point);
  453.                 (void)fclose(data_file);
  454.                 (void)printf("Origin: %d '%s'\n", user_count, origin_to_use);
  455.                 return(TRUE);
  456.             }
  457.  
  458.             user_count++;
  459.         }
  460.     }
  461.  
  462.     (void)fclose(data_file);
  463.     (void)strcpy(origin_to_use, default_origin);
  464.     (void)printf("Origin: DEFAULT\n");
  465.     return(FALSE);
  466. }
  467.  
  468. /* **********************************************************************
  469.    * Apply the origin line to all alive folders.                        *
  470.    *                                                                    *
  471.    ********************************************************************** */
  472.  
  473. static void apply_origin_line(void)
  474. {
  475.     unsigned int loop;
  476.     FILE *ra_file;
  477.     char file_name[201];
  478.     unsigned char origin_length;
  479.     int folder_count, result;
  480.     char report[101];
  481.  
  482.     (void)sprintf(file_name, "%s%s", full_path, "MESSAGES.RA");
  483.  
  484.     if ((ra_file = fopen(file_name, "r+b")) == (FILE *)NULL) {
  485.         (void)printf("Couldn't find file: %s!\n", file_name);
  486.         fcloseall();
  487.         exit(10);
  488.     }            
  489.  
  490.     origin_length = strlen(origin_to_use);
  491.     folder_count = 0;
  492.  
  493.     print_buffer("\nSetting origins...\n");
  494.  
  495.     for (loop = 0; loop < 200; loop++) {
  496.     fseek(ra_file, (long)sizeof(struct Messages_RA) * loop, SEEK_SET);
  497.         result = fread(&MRA, sizeof(struct Messages_RA), 1, ra_file);
  498.  
  499.         if (result != 1) {
  500.             (void)printf("Couldn't read record %d from file %s! Result %d\n",
  501.                 loop, file_name, result);
  502.  
  503.             fcloseall();
  504.             exit(10);
  505.         }
  506.  
  507.         if (0 != MRA.title_length) {
  508.             MRA.origin_length = origin_length;
  509.             (void)strncpy(MRA.origin, origin_to_use, origin_length);
  510.         fseek(ra_file, (long)sizeof(struct Messages_RA) * loop, SEEK_SET);
  511.  
  512.             result = fwrite(&MRA, sizeof(struct Messages_RA), 1, ra_file);
  513.  
  514.             if (result != 1) {
  515.                 (void)printf("Couldn't write record %d from file %s! Result: \n",
  516.                     loop, file_name, result);
  517.  
  518.                 fcloseall();
  519.                 exit(10);
  520.             }
  521.  
  522.             folder_count++;
  523.         }
  524.     }
  525.  
  526.     (void)fclose(ra_file);
  527.  
  528.     (void)sprintf(report,
  529.     "Origin line changed in %d folders\n",
  530.     folder_count);
  531.  
  532.     print_buffer(report);
  533. }
  534.  
  535. /* **********************************************************************
  536.    * Update the user data file with the new origin line.                *
  537.    *                                                                    *
  538.    ********************************************************************** */
  539.  
  540. static void update_user_data_file(char *new_origin_line)
  541. {
  542.     FILE *data_file, *temp_file;
  543.     char file_name[201];
  544.     char record[201];
  545.     int loop;
  546.  
  547.     (void)sprintf(file_name, "%s%s", full_path, "U-ORIG.DAT");
  548.  
  549.     if ((data_file = fopen(file_name, "rt")) == (FILE *)NULL) {
  550.         if ((data_file = fopen(file_name, "wt")) == (FILE *)NULL) {
  551.             (void)printf("I can't create file: %s!\n", file_name);
  552.             fcloseall();
  553.             exit(10);
  554.         }
  555.  
  556.         (void)fputs(new_origin_line, data_file);
  557.         (void)fclose(data_file);
  558.         return;
  559.     }
  560.  
  561.     if ((temp_file = fopen("U-ORIG.TMP", "wt")) == (FILE *)NULL) {
  562.         (void)printf("I can't create work file: U-ORIG.TMP!\n");
  563.         fcloseall();
  564.         exit(11);
  565.     }
  566.  
  567. /*
  568.  * Read up to the users record, dumping it into the temp file.
  569.  */
  570.  
  571.     for (loop = 0; loop < user_count; loop++) {
  572.         (void)fgets(record, 200, data_file);
  573.  
  574.         if (! feof(data_file)) {
  575.             (void)fputs(record, temp_file);
  576.         }
  577.     }
  578.  
  579. /*
  580.  * Write new record to temp file, read old record from original file
  581.  */
  582.  
  583.     (void)fputs(user_name, temp_file);
  584.     (void)fputs("   ", temp_file);
  585.     (void)fputs(new_origin_line, temp_file);
  586.     (void)fputs("\n", temp_file);
  587.     (void)fgets(record, 200, data_file);
  588.  
  589. /*
  590.  * Finish reading original file, dumping to temp file.
  591.  */
  592.  
  593.     while (! feof(data_file)) {
  594.         (void)fgets(record, 200, data_file);
  595.  
  596.         if (! feof(data_file)) {
  597.             (void)fputs(record, temp_file);
  598.         }
  599.     }
  600.  
  601.     (void)fclose(data_file);
  602.     (void)fclose(temp_file);
  603.     unlink(file_name);
  604.     rename("U-ORIG.TMP", file_name);
  605. }
  606.  
  607. /* **********************************************************************
  608.    * Allow the origin line to be added to the file if it's not found    *
  609.    * else if it was found, display it and ask if it should be changed.  *
  610.    * If it should be, ask for the new one. Then display the new one and *
  611.    * ask if it's acceptable. If it is, update the data file and then    *
  612.    * apply the new update to the folders.                               *
  613.    *                                                                    *
  614.    ********************************************************************** */
  615.  
  616. static void allow_change_addition_of_origin(BOOL found)
  617. {
  618.     char input_buffer[101];
  619.     char new_origin_line[101];
  620.  
  621.     if (! found) {
  622. another_ask_again:
  623.         print_buffer("\n\nYou have no origin line.\n\n");
  624.         print_buffer("Would you like to create one? ");
  625.         input(input_buffer, 10);
  626.  
  627.         if (toupper(input_buffer[0]) == 'N') return;
  628.         if (toupper(input_buffer[0]) != 'Y') goto another_ask_again;
  629.     }
  630.     else {
  631. ask_this_again:
  632.         print_buffer("\n\nYour origin line is:\n   '");
  633.         print_buffer(origin_to_use);
  634.         print_buffer("'\n\nWould you like to change it? ");
  635.         input(input_buffer, 10);
  636.  
  637.         if (toupper(input_buffer[0]) == 'N') return;
  638.         if (toupper(input_buffer[0]) != 'Y') goto ask_this_again;
  639.     }
  640.  
  641. try_it_again:
  642.     print_buffer("\n\nEnter new origin line:\n");
  643.     print_buffer("Must be from 10 to 60 characters in length:\n   :");
  644.     input(new_origin_line, 60);
  645.  
  646.     if (strlen(new_origin_line) < 10) return;
  647.  
  648. ask_it_again:
  649.     print_buffer("\n\nI have '");
  650.     print_buffer(new_origin_line);
  651.     print_buffer("'\n");
  652.     print_buffer("\n\nShould I (K)eep, (T)ry again, (Q)uit: ");
  653.     input(input_buffer, 10);
  654.  
  655.     if (toupper(input_buffer[0]) == 'Q') return;
  656.     if (toupper(input_buffer[0]) == 'T') goto try_it_again;
  657.     if (toupper(input_buffer[0]) != 'K') goto ask_it_again;
  658.  
  659.     (void)strcpy(origin_to_use, new_origin_line);
  660.     update_user_data_file(new_origin_line);
  661. }
  662.  
  663. /* **********************************************************************
  664.    * Here is the main entry point.                                      *
  665.    *                                                                    *
  666.    ********************************************************************** */
  667.  
  668. void main(int argc, char *argv[])
  669. {
  670.     char option[201];
  671.     BOOL found;
  672.  
  673.     clrscr();
  674.     extract_configuration();
  675.     extract_door_file();
  676.  
  677.     local_mode = FALSE;
  678.  
  679.     found = match_user_name();
  680.  
  681.     if (argc > 1)
  682.     (void)strcpy(option, argv[1]);
  683.     else
  684.     option[0] = (char)NULL;
  685.  
  686.     if (! strnicmp(option, "update", 6)) {
  687.         print_buffer("\n\nUser-Origin Version 1.0. \n");
  688.  
  689.         if (security_value >= allowed_security) {
  690.             allow_change_addition_of_origin(found);
  691.             apply_origin_line();
  692.         }
  693.         else {
  694.             print_buffer("Your security level doesn't allow updates ");
  695.             print_buffer("to your origin line.\n");
  696.             delay(200);
  697.         }
  698.  
  699.         fcloseall();
  700.         exit(0);
  701.     }
  702.     else if (! strnicmp(option, "apply", 5)) {
  703.         apply_origin_line();
  704.         fcloseall();
  705.         exit(0);
  706.     }
  707.     else {
  708.         (void)strcpy(origin_to_use, default_origin);
  709.         apply_origin_line();
  710.         fcloseall();
  711.         exit(0);
  712.     }
  713. }
  714.  
  715.  
  716.